'use strict';

const fs = require('fs');
const path = require('path');

const createConfig = require('uni-config-center');
const uidConfig = createConfig({
	pluginId: 'uni-id'
});

const uidPay = require('uni-pay');

const jobname = 'job-hour';

const db = uniCloud.database();
const dbcmd = db.command;

exports.main = async (event, context) => {
	let response = {
		code: 0,
		datas: {
			unrefundGroupOrder: {
				count: 0
			}
		}
	};
	const ip = context.CLIENTIP;
	// 未退款的拼团订单 自动退款
	response.datas.unrefundGroupOrder.count = await doUnrefundGroupOrder(ip);
	
	//返回数据给客户端
	return response;
};

// 未退款的拼团订单 自动退款
const doUnrefundGroupOrder = async (ip) => {
	let count = 0;
	let res = {};
	let rows = 100;
	do {
		// 未退款的拼团订单
		res = await unrefundGroupOrder(ip, rows);
		count += res.count;
	} while (res.count >= rows)
	
	return count;
}
const unrefundGroupOrder = async (ip, rows) => {
	const nowdate = Date.now();
	const res = {
		count: 0
	};
	
	
	const orderRes = await db.collection('usemall-order')
		.where({
			group_id: dbcmd.exists(true),
			order_pay_state: '已付款',
			order_refund_state: dbcmd.in(['待退款'])
		})
		.field({
			order_actural_paid: true,
			order_pay_way: true,
			order_id: true,
			state: true,
			order_from: true,
			out_trade_no: true,
			order_member_name: true,
			order_member_openid: true,
			order_member_headimg: true,
			create_uid: true
		})
		.limit(rows)
		.get();
	
	if (orderRes.data && orderRes.data.length) {
		res.count = orderRes.data.length;
	
		// 调用退款函数进行对应退款操作
		// 退款成功，修改订单退款状态 已退款、记录日志
		// 退款失败，记录对应的退款失败日志
		// 发送 退款成功|失败 消息通知
	
		const orderIds = [];
		const orderLogs = [];
		
		for (let i = 0; i < orderRes.data.length; i++) {
			const order = orderRes.data[i];
			
			try {
				// 调用退款函数进行对应退款操作
				await refund(order, ip, nowdate);
			} catch(e) {
				orderLogs.push({
					order_id: order.order_id,
					log_type: '自动退款',
					remark: `自动退款失败，待下一次处理。${e.message}`,
					current_state: order.state,
					prev_state: order.state,
					ip: ip,
					is_delete: 0,
					create_uid: jobname,
					create_time: nowdate
				});
				continue;
			}
			
			
			let orderUpdate = {
				order_refund_state: '已退款',
				order_refund_amount: order.order_actural_paid,
				order_refund_reason: '拼团失败，系统自动退款',
				order_refund_remark: '原支付方式退回',
				
				// 修改时间
				last_modify_time: nowdate,
				last_modify_uid: jobname,
				last_modify_uname: jobname
			}
			
			// 修改订单退款状态为已退款
			await db.collection('usemall-order')
				.doc(order._id)
				.update(orderUpdate);
				
			orderLogs.push({
				order_id: order.order_id,
				log_type: '自动退款',
				remark: `拼团已失败订单，系统已自动退款`,
				current_state: order.state,
				prev_state: order.state,
				ip: ip,
				is_delete: 0,
				create_uid: jobname,
				create_time: nowdate
			});
		}
	
		res.addLogRes = await db.collection('usemall-order-log').add(orderLogs);
	}
	
	return res;
}

/**
 * 退款操作
 * 	1. 判断支付方式，根据支付方式进行相对应退款操作
 * 	2. 返回 退款成功、退款失败
 */
const refund = async (order, ip, nowdate) => {
	// 退款金额 = 实付款金额
	const refundFee = order.order_actural_paid;
	
	switch (order.order_pay_way){
		case '微信支付':
			let wxpayConfig;
			if (order.order_from == 'app') {
				// APP 微信支付
				wxpayConfig = uidConfig.config('app.wxpay');
			} else if (order.order_from == '微信公众号') {
				// 微信公众号 微信支付
				wxpayConfig = uidConfig.config('h5-weixin.pay');
			} else {
				// 微信小程序 微信支付
				wxpayConfig = uidConfig.config('mp-weixin.pay');
			}
				
			const wxOptions = {
				...wxpayConfig,
				pfx: fs.readFileSync(path.resolve(__dirname, 'cert/wxpay/apiclient_cert.p12')),
				passphrase: 'password'
			}
			const uniWxpayIns = uidPay.initWeixin(wxOptions);
			const refundRes = await uniWxpayIns.refund({
				outTradeNo: order.out_trade_no,
				outRefundNo: order.out_trade_no,
				totalFee: order.order_actural_paid,
				refundFee: refundFee
			});
				
			if (refundRes.returnCode != 'SUCCESS') {
				throw new Error(`${order.order_pay_way}退款[${refundRes.returnMsg}]`);
			}
			
			// 写入申请退款数据
			await db.collection('usemall-order-refund').add({
				order_id: order.order_id,
				refund_money: refundFee,
				member_guid: order.create_uid,
				member_name: order.order_member_name,
				member_headimg: order.order_member_headimg,
				goods_state: '未收到货',
				reason: '拼团已失败订单，系统自动退款',
				desc: '',
				imgs: [],
				remark: '已自动退款',
				version: 1,
				state: '已退款',
				is_delete: 0,
				create_uid: jobname,
				create_time: nowdate,
				create_uname: jobname
			});
			break;
		case '零钱支付':
			await db.collection('usemall-member').doc(order.create_uid).update({
				// 退回用户零钱
				member_amount: dbcmd.inc(refundFee)
			});
				
			await db.collection('usemall-member-money-log').add({
				order_id: order.order_id,
				money: refundFee,
				money_fmt: '+' + refundFee / 100,
				source: '拼团订单退款',
				type: '退款',
				remark: `拼团订单退款+${refundFee / 100}`,
				ip: ip,
				is_delete: 0,
				create_uid: order.create_uid,
				create_time: nowdate
			});
			break;
		default:
			throw new Error(`${order.order_pay_way}退款未支持`);
	}
	
	// 修改用户消费金额
	const memberRes = await db.collection('usemall-member').doc(order.create_uid).update({
		member_monetary: dbcmd.inc(-refundFee)
	});
	
}

/**
 * 将 UTC+0 转换为 UTC+8
 */
function toDateUTC8(date) {
	if (uniCloud.$provider == 'alipay') {
		// 支付宝云，默认为 UTC+8
		return date;
	}
	
	// 小时 UTC+0 转换为 UTC+8
	date.setHours(date.getHours() + 8);
	return date;
}